package com.code.google.p.jyve;

import java.awt.Color;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.NumberFormat;
import java.text.ParseException;

import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.ListSelectionModel;
import javax.swing.SpringLayout;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.eclipse.wb.swing.FocusTraversalOnArray;

import com.code.google.p.jyve.berekeningen.Berekening;
import com.code.google.p.jyve.database.Stof;
import com.code.google.p.jyve.indicatoren.Indicator;

public class Window {

	private static final String ZOUTZUUR = "HCl";
	private static final String NATRONLOOG = "OH -";
	private static String VERSION = "1.2.1";//Programmaversie

	private JFrame frmJyveTitratiecurven;
	private JTextField textField_formule;
	private JTextField textField_molariteit_oplossing;
	private JTextField textField_volume;
	private JTextField textField_molariteit_titrant;
	private Graph graph;
	private JComboBox comboBox_ZuurBase;
	private DefaultListModel berekeningen = new DefaultListModel();
	private BerekeningHolder selectedBerekening;
	private DefaultListModel indicatoren = new DefaultListModel();
	private IndicatorHolder selectedIndicator;
	private JTextPane error_label;
	private GraphWindow graphWindow;
	private DatabaseWindow databaseWindow;
	private AboutBox aboutBox;
	private JList listBerekeningen;
	private NumberFormat format = NumberFormat.getInstance();
	private JList list;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {		
		EventQueue.invokeLater(new Runnable() {
			public void run() {				
				try {
					Window window = new Window();
					window.frmJyveTitratiecurven.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public Window() {		
		initIndicatoren();
		initBerekeningen();
		initialize();
	}

	private void initBerekeningen(){
		BerekeningHolder holder = new BerekeningHolder("Curve 1");
		berekeningen.addElement(holder);
		selectedBerekening = holder;
	}

	private void initIndicatoren(){
		Indicator[] indicatoren = Indicator.getIndicatoren();
		for (Indicator i : indicatoren)	this.indicatoren.addElement(new IndicatorHolder(i));
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frmJyveTitratiecurven = new JFrame();
		frmJyveTitratiecurven.setIconImage(Toolkit.getDefaultToolkit().getImage(Window.class.getResource("/com/code/google/p/jyve/Jyve3.png")));
		frmJyveTitratiecurven.setTitle("Jyve titratiecurven");
		frmJyveTitratiecurven.getContentPane().setBackground(Color.WHITE);
		frmJyveTitratiecurven.setForeground(Color.BLACK);
		frmJyveTitratiecurven.setBounds(20, 20, 1263, 743);
		frmJyveTitratiecurven.setExtendedState(JFrame.MAXIMIZED_BOTH);
		frmJyveTitratiecurven.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frmJyveTitratiecurven.addWindowListener(new WindowListener(){

			@Override
			public void windowActivated(WindowEvent arg0) {
				// Niks
			}

			@Override
			public void windowClosed(WindowEvent arg0) {
				// Niks
			}

			@Override
			public void windowClosing(WindowEvent arg0) {
				Stof.closeDatabase();				
			}

			@Override
			public void windowDeactivated(WindowEvent arg0) {
				// Niks
			}

			@Override
			public void windowDeiconified(WindowEvent arg0) {
				// Niks
			}

			@Override
			public void windowIconified(WindowEvent arg0) {
				// Niks
			}

			@Override
			public void windowOpened(WindowEvent arg0) {
				// Niks
			}

		});
		JPanel panel = new JPanel();
		panel.setBackground(Color.WHITE);

		comboBox_ZuurBase = new JComboBox();
		comboBox_ZuurBase.setModel(new DefaultComboBoxModel(new String[] {"Zuur", "Base"}));

		textField_formule = new JTextField();
		textField_formule.setColumns(10);

		textField_molariteit_oplossing = new JTextField();
		textField_molariteit_oplossing.setColumns(10);

		textField_volume = new JTextField();
		textField_volume.setColumns(10);

		graph = new Graph();
		FlowLayout fl_graph = (FlowLayout) graph.getLayout();
		fl_graph.setAlignment(FlowLayout.RIGHT);
		SpringLayout springLayout = new SpringLayout();
		springLayout.putConstraint(SpringLayout.WEST, panel, 0, SpringLayout.WEST, frmJyveTitratiecurven.getContentPane());
		springLayout.putConstraint(SpringLayout.EAST, panel, -6, SpringLayout.WEST, graph);
		springLayout.putConstraint(SpringLayout.WEST, graph, 388, SpringLayout.WEST, frmJyveTitratiecurven.getContentPane());
		springLayout.putConstraint(SpringLayout.EAST, graph, 0, SpringLayout.EAST, frmJyveTitratiecurven.getContentPane());
		springLayout.putConstraint(SpringLayout.SOUTH, graph, 0, SpringLayout.SOUTH, frmJyveTitratiecurven.getContentPane());
		springLayout.putConstraint(SpringLayout.NORTH, graph, 0, SpringLayout.NORTH, frmJyveTitratiecurven.getContentPane());
		springLayout.putConstraint(SpringLayout.NORTH, panel, 0, SpringLayout.NORTH, frmJyveTitratiecurven.getContentPane());
		springLayout.putConstraint(SpringLayout.SOUTH, panel, 709, SpringLayout.NORTH, frmJyveTitratiecurven.getContentPane());
		frmJyveTitratiecurven.getContentPane().setLayout(springLayout);
		frmJyveTitratiecurven.getContentPane().add(panel);

		textField_molariteit_titrant = new JTextField();
		textField_molariteit_titrant.setColumns(10);

		JLabel lblMolariteitmollTitrant = new JLabel("Molariteit (mol/L) titrant");
		lblMolariteitmollTitrant.setFont(new Font("Tahoma", Font.PLAIN, 11));

		JButton btnCheck = new JButton("Check in database");
		btnCheck.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnCheck.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				error_label.setText(null);
				Stof stof;
				boolean check = (stof = Stof.findInstance(textField_formule.getText())) != null;
				if (check) {
					if ((stof.isZuur()) && (!stof.isBase())) comboBox_ZuurBase.setSelectedIndex(1);
					else if ((stof.isBase()) && (!stof.isZuur())) comboBox_ZuurBase.setSelectedIndex(0);
				}
				else error_label.setText("Stof niet gevonden in database");
			}
		});

		final JButton btnAdd = new JButton("Voeg toe");
		btnAdd.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnAdd.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				if (!graph.containsIndicator(selectedIndicator.indicator)) graph.addIndicator(selectedIndicator.indicator);
				selectedIndicator.select();
				list.repaint();
			}
		});

		final JButton btnVerwijderIndicator = new JButton("Wegdoen");
		btnVerwijderIndicator.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnVerwijderIndicator.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				graph.removeIndicator(selectedIndicator.indicator);
				selectedIndicator.unselect();
				list.repaint();
			}
		});

		final JScrollPane scrollPane = new JScrollPane();
		scrollPane.setToolTipText("Indicatoren");

		JLabel lblIndicatoren = new JLabel("Indicatoren");
		scrollPane.setColumnHeaderView(lblIndicatoren);

		list = new JList();
		list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
		list.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent arg0) {
				selectedIndicator = ((IndicatorHolder)indicatoren.elementAt(list.getSelectedIndex()));
			}
		});
		scrollPane.setViewportView(list);
		list.setModel(indicatoren);
		list.setVisibleRowCount(-1);

		JScrollPane scrollPane_1 = new JScrollPane();
		scrollPane_1.setToolTipText("Berekeningen");

		JLabel lblBerekeningen = new JLabel("Curves");
		scrollPane_1.setColumnHeaderView(lblBerekeningen);

		listBerekeningen = new JList();
		scrollPane_1.setViewportView(listBerekeningen);		
		listBerekeningen.setModel(berekeningen);
		listBerekeningen.setSelectedIndex(0);

		JButton btnNieuw = new JButton("Nieuw");
		btnNieuw.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnNieuw.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				addBerekening();
			}
		});

		JButton btnTeken = new JButton("Teken");
		btnTeken.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnTeken.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				if (selectedBerekening == null) addBerekening();
				Berekening berekening = createBerekening();
				if (berekening != null){
					if (selectedBerekening.berekening != null) graph.removeBerekening(selectedBerekening.berekening);
					selectedBerekening.berekening = berekening;
					selectedBerekening.text = textField_formule.getText() + " : " + textField_molariteit_oplossing.getText() + " M";
					listBerekeningen.repaint();
					graph.addBerekening(selectedBerekening.berekening);
				}

			}
		});

		JButton btnVerwijderBerekening = new JButton("Verwijder");
		btnVerwijderBerekening.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnVerwijderBerekening.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				int selectedIndex = listBerekeningen.getSelectedIndex();
				berekeningen.remove(selectedIndex);
				graph.removeBerekening(selectedBerekening.berekening);
				if (berekeningen.size() != 0) listBerekeningen.setSelectedIndex(selectedIndex - 1);
				else selectedBerekening = null;
			}
		});

		error_label = new JTextPane();
		error_label.setForeground(Color.RED);

		JLabel lblDeOplossing = new JLabel("Oplossing");
		lblDeOplossing.setFont(new Font("Tahoma", Font.BOLD, 13));

		JLabel lblTitrant = new JLabel("Titrant");
		lblTitrant.setFont(new Font("Tahoma", Font.BOLD, 13));

		JLabel lblVolumemlOplossing = new JLabel("Volume (mL) oplossing");
		lblVolumemlOplossing.setFont(new Font("Tahoma", Font.PLAIN, 11));

		JLabel lblMolariteitmollOplossing = new JLabel("Molariteit (mol/L) oplossing");
		lblMolariteitmollOplossing.setFont(new Font("Tahoma", Font.PLAIN, 11));

		JLabel lblFormuleOfNaam = new JLabel("Formule of naam");
		lblFormuleOfNaam.setFont(new Font("Tahoma", Font.PLAIN, 11));
		GroupLayout gl_panel = new GroupLayout(panel);
		gl_panel.setHorizontalGroup(
				gl_panel.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panel.createSequentialGroup()
						.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
								.addGroup(gl_panel.createSequentialGroup()
										.addGap(10)
										.addComponent(lblDeOplossing, GroupLayout.PREFERRED_SIZE, 154, GroupLayout.PREFERRED_SIZE)
										.addGap(33)
										.addComponent(lblTitrant, GroupLayout.PREFERRED_SIZE, 46, GroupLayout.PREFERRED_SIZE))
										.addGroup(gl_panel.createSequentialGroup()
												.addContainerGap()
												.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
														.addGroup(gl_panel.createSequentialGroup()
																.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
																		.addComponent(btnTeken, GroupLayout.PREFERRED_SIZE, 169, GroupLayout.PREFERRED_SIZE)
																		.addComponent(textField_volume, GroupLayout.PREFERRED_SIZE, 169, GroupLayout.PREFERRED_SIZE))
																		.addGap(18)
																		.addComponent(error_label, GroupLayout.PREFERRED_SIZE, 169, GroupLayout.PREFERRED_SIZE))
																		.addComponent(lblVolumemlOplossing)
																		.addGroup(gl_panel.createParallelGroup(Alignment.TRAILING, false)
																				.addGroup(gl_panel.createSequentialGroup()
																						.addGroup(gl_panel.createParallelGroup(Alignment.TRAILING, false)
																								.addComponent(btnCheck, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
																								.addComponent(textField_formule, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 169, Short.MAX_VALUE))
																								.addGap(18)
																								.addComponent(comboBox_ZuurBase, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
																								.addGroup(Alignment.LEADING, gl_panel.createSequentialGroup()
																										.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
																												.addComponent(textField_molariteit_oplossing, GroupLayout.PREFERRED_SIZE, 169, GroupLayout.PREFERRED_SIZE)
																												.addComponent(lblMolariteitmollOplossing))
																												.addGap(18)
																												.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
																														.addComponent(lblMolariteitmollTitrant, GroupLayout.PREFERRED_SIZE, 169, GroupLayout.PREFERRED_SIZE)
																														.addComponent(textField_molariteit_titrant, GroupLayout.PREFERRED_SIZE, 169, GroupLayout.PREFERRED_SIZE))))))
																														.addGroup(gl_panel.createSequentialGroup()
																																.addContainerGap()
																																.addComponent(lblFormuleOfNaam))
																																.addGroup(gl_panel.createSequentialGroup()
																																		.addContainerGap()
																																		.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
																																				.addGroup(gl_panel.createSequentialGroup()
																																						.addComponent(scrollPane_1, GroupLayout.PREFERRED_SIZE, 169, GroupLayout.PREFERRED_SIZE)
																																						.addGap(18)
																																						.addComponent(scrollPane, GroupLayout.PREFERRED_SIZE, 169, GroupLayout.PREFERRED_SIZE))
																																						.addGroup(gl_panel.createSequentialGroup()
																																								.addComponent(btnNieuw, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE)
																																								.addPreferredGap(ComponentPlacement.RELATED)
																																								.addComponent(btnVerwijderBerekening, GroupLayout.PREFERRED_SIZE, 89, GroupLayout.PREFERRED_SIZE)
																																								.addGap(18)
																																								.addComponent(btnAdd)
																																								.addPreferredGap(ComponentPlacement.RELATED)
																																								.addComponent(btnVerwijderIndicator, GroupLayout.PREFERRED_SIZE, 87, GroupLayout.PREFERRED_SIZE)))))
																																								.addContainerGap(16, Short.MAX_VALUE))
				);
		gl_panel.setVerticalGroup(
				gl_panel.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panel.createSequentialGroup()
						.addGap(9)
						.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
								.addComponent(lblDeOplossing, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE)
								.addComponent(lblTitrant, GroupLayout.PREFERRED_SIZE, 14, GroupLayout.PREFERRED_SIZE))
								.addPreferredGap(ComponentPlacement.UNRELATED)
								.addComponent(lblFormuleOfNaam)
								.addPreferredGap(ComponentPlacement.RELATED)
								.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
										.addComponent(textField_formule, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
										.addComponent(comboBox_ZuurBase, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
										.addGap(4)
										.addComponent(btnCheck)
										.addGap(15)
										.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
												.addComponent(lblMolariteitmollOplossing)
												.addComponent(lblMolariteitmollTitrant))
												.addPreferredGap(ComponentPlacement.RELATED)
												.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
														.addGroup(gl_panel.createSequentialGroup()
																.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
																		.addComponent(textField_molariteit_oplossing, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
																		.addComponent(textField_molariteit_titrant, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
																		.addGap(27)
																		.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
																				.addGroup(gl_panel.createSequentialGroup()
																						.addComponent(textField_volume, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
																						.addPreferredGap(ComponentPlacement.RELATED)
																						.addComponent(btnTeken))
																						.addComponent(error_label, GroupLayout.PREFERRED_SIZE, 37, GroupLayout.PREFERRED_SIZE)))
																						.addGroup(gl_panel.createSequentialGroup()
																								.addGap(31)
																								.addComponent(lblVolumemlOplossing)))
																								.addGap(18)
																								.addGroup(gl_panel.createParallelGroup(Alignment.LEADING, false)
																										.addComponent(scrollPane)
																										.addComponent(scrollPane_1, GroupLayout.PREFERRED_SIZE, 127, GroupLayout.PREFERRED_SIZE))
																										.addPreferredGap(ComponentPlacement.RELATED)
																										.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
																												.addComponent(btnNieuw)
																												.addComponent(btnVerwijderBerekening)
																												.addComponent(btnAdd)
																												.addComponent(btnVerwijderIndicator))
																												.addContainerGap(297, Short.MAX_VALUE))
				);
		panel.setLayout(gl_panel);
		panel.setFocusTraversalPolicy(new FocusTraversalOnArray(new Component[]{textField_formule, textField_molariteit_oplossing, textField_volume, textField_molariteit_titrant, btnCheck, comboBox_ZuurBase, btnTeken, lblDeOplossing, lblTitrant, error_label, lblVolumemlOplossing, lblMolariteitmollOplossing, lblMolariteitmollTitrant, lblFormuleOfNaam, scrollPane_1, lblBerekeningen, listBerekeningen, scrollPane, lblIndicatoren, list, btnNieuw, btnVerwijderBerekening, btnAdd, btnVerwijderIndicator}));
		frmJyveTitratiecurven.getContentPane().add(graph);
		listBerekeningen.addListSelectionListener(new ListSelectionListener(){

			@Override
			public void valueChanged(ListSelectionEvent arg0) {
				int selectedIndex;
				if ((selectedIndex = listBerekeningen.getSelectedIndex()) != -1){
					BerekeningHolder ber = (BerekeningHolder) berekeningen.get(selectedIndex);
					selectedBerekening = ber;
					if (ber.berekening != null){
						textField_molariteit_oplossing.setText(format.format(ber.berekening.getMolariteitOplossing()));
						textField_molariteit_titrant.setText(format.format(ber.berekening.getMolariteitTitrant()));
						textField_volume.setText(format.format(ber.berekening.getVolumeOplossing()));
						textField_formule.setText(ber.berekening.getNaamOplossing());
						comboBox_ZuurBase.setSelectedIndex(ber.berekening.getTypeTitrant());
					}
				}
			}

		});

		JMenuBar menuBar = new JMenuBar();
		frmJyveTitratiecurven.setJMenuBar(menuBar);

		JMenuItem mntmDatabase = new JMenuItem("Database");
		menuBar.add(mntmDatabase);
		mntmDatabase.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				databaseWindow.show();
			}
		});

		JMenuItem mntmGrafiek = new JMenuItem("Grafiek");
		menuBar.add(mntmGrafiek);

		JMenu mnNewMenu_1 = new JMenu("Help");
		menuBar.add(mnNewMenu_1);

		JMenuItem mntmNewMenuItem_2 = new JMenuItem("Info");
		mntmNewMenuItem_2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				aboutBox.setVisible(true);
			}
		});
		mnNewMenu_1.add(mntmNewMenuItem_2);

		JMenuItem mntmNewMenuItem_3 = new JMenuItem("Help");
		mntmNewMenuItem_3.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				Desktop desktop = Desktop.getDesktop();
				try {
					desktop.browse(new URI("https://docs.google.com/document/d/1Enr59pjTX8WY_NrXzSH9uM8-3gq7Dqex1qhths5zRXY/edit"));
				}
				catch (IOException exception){
					exception.printStackTrace();
				} catch (URISyntaxException e) {
					e.printStackTrace();
				}
			}
		});
		mnNewMenu_1.add(mntmNewMenuItem_3);
		frmJyveTitratiecurven.setFocusTraversalPolicy(new FocusTraversalOnArray(new Component[]{frmJyveTitratiecurven.getContentPane(), panel, textField_molariteit_oplossing, textField_molariteit_titrant, lblMolariteitmollTitrant, btnVerwijderIndicator, btnCheck, scrollPane, textField_volume, lblIndicatoren, comboBox_ZuurBase, list, btnAdd, scrollPane_1, lblBerekeningen, listBerekeningen, btnNieuw, textField_formule, btnTeken, btnVerwijderBerekening, error_label, lblDeOplossing, lblTitrant, graph, menuBar, mntmDatabase, mntmGrafiek, mnNewMenu_1, mntmNewMenuItem_2, mntmNewMenuItem_3}));
		mntmGrafiek.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent arg0) {
				graphWindow.show();
			}

		});




		graphWindow = new GraphWindow(graph);
		frmJyveTitratiecurven.getContentPane().setFocusTraversalPolicy(new FocusTraversalOnArray(new Component[]{textField_volume, textField_formule, textField_molariteit_oplossing, comboBox_ZuurBase, textField_molariteit_titrant, panel, lblMolariteitmollTitrant, btnCheck, btnVerwijderIndicator, scrollPane, lblIndicatoren, list, btnAdd, scrollPane_1, lblBerekeningen, listBerekeningen, btnNieuw, btnTeken, btnVerwijderBerekening, error_label, lblDeOplossing, lblTitrant, graph}));

		databaseWindow = new DatabaseWindow();
		aboutBox = new AboutBox(VERSION);
	}

	private Berekening createBerekening(){
		error_label.setText(null);
		double molOplossing, molTitrant, volumeOplossing = 0;

		try{
			molOplossing = format.parse(textField_molariteit_oplossing.getText()).doubleValue();
		}
		catch (ParseException e){
			error_label.setText("Molariteit oplossing is geen geldig getal");
			return null;
		}
		try{
			molTitrant = format.parse(textField_molariteit_titrant.getText()).doubleValue();
		}
		catch (ParseException e){
			error_label.setText("Molariteit titrant is geen geldig getal");
			return null;
		}
		try{
			volumeOplossing = format.parse(textField_volume.getText()).doubleValue();
		}
		catch (ParseException e){
			error_label.setText("Volume oplossing is geen geldig getal");
			return null;
		}
		String naamStof = textField_formule.getText();

		Stof stof = Stof.findInstance(naamStof);

		if (stof == null) {
			error_label.setText("Stof niet gevonden in database");
			return null;
		}

		Stof titrant = Stof.findInstance(comboBox_ZuurBase.getSelectedIndex() == 0 ? ZOUTZUUR : NATRONLOOG);

		if (titrant == null) {
			error_label.setText("Jammer genoeg werkt deze functie nog niet");
			return null;
		}
		Berekening ber = new Berekening.Builder(stof, titrant)
		.molariteitOplossing(molOplossing)
		.molariteitTitrant(molTitrant)
		.volumeOplossing(volumeOplossing)
		.build();
		return ber;
	}

	private void addBerekening() {
		berekeningen.addElement(new BerekeningHolder("Curve " + (berekeningen.getSize() + 1)));
		listBerekeningen.setSelectedIndex(berekeningen.getSize() - 1);
	}

	private class BerekeningHolder{
		private Berekening berekening;
		private String text;

		private BerekeningHolder(String text){
			this.text = text;
		}

		@Override
		public String toString() {
			return text;
		}
	}

	private class IndicatorHolder {
		private Indicator indicator;
		private boolean selected;

		private IndicatorHolder(Indicator indicator){
			this.indicator = indicator;
		}

		private void select(){
			selected = true;
		}

		private void unselect(){
			selected = false;
		}

		@Override
		public String toString() {
			return indicator.getNaam() + (selected ? " X" : "");
		}
	}
}
